package cn.zcltd.btg.set.core;

import cn.zcltd.btg.set.ParamSource;
import cn.zcltd.btg.set.ParamType;
import cn.zcltd.btg.set.ToJson;
import cn.zcltd.btg.set.ToXml;
import cn.zcltd.btg.set.exception.BtgSetRuntimerException;
import cn.zcltd.btg.set.util.StringUtil;
import cn.zcltd.btg.sutil.EmptyUtil;

/**
 * 参数
 */
public class Param implements ToJson, ToXml {

    private ParamType type; //参数数据类型（必须）
    private String datePattern; //当为Date类型时可指定时间格式化参数

    private String id; //参数id（必须）
    private String name; //参数name
    private String value; //参数值
    private String desc; //参数描述
    private String remark; //参数备注

    private ParamSource source; //参数类型（必须）
    private Module module; //参数所属模块（module>param必须，config>>param为空）
    private Config config; //参数所属配置（必须）

    public Param(String id, String name, ParamType type, String value, Module module) {
        if (EmptyUtil.isEmpty(id)) {
            throw new BtgSetRuntimerException("id must not be null");
        }
        if (null == type) {
            throw new BtgSetRuntimerException("type must not be null");
        }
        if (null == module) {
            throw new BtgSetRuntimerException("module must not be null");
        }
        this.id = id;
        this.name = name;
        this.type = type;
        this.value = value;

        this.source = ParamSource.MODULE;
        this.module = module;
        this.config = module.getConfig();
    }

    public Param(String id, String name, ParamType type, String value, Config config) {
        if (EmptyUtil.isEmpty(id)) {
            throw new BtgSetRuntimerException("id must not be null");
        }
        if (null == type) {
            throw new BtgSetRuntimerException("type must not be null");
        }
        if (null == config) {
            throw new BtgSetRuntimerException("config must not be null");
        }
        this.id = id;
        this.name = name;
        this.type = type;
        this.value = value;

        this.source = ParamSource.CONFIG;
        this.config = config;
    }

    public ParamType getType() {
        return type;
    }

    public void setType(ParamType type) {
        this.type = type;
    }

    public String getDatePattern() {
        return datePattern;
    }

    public void setDatePattern(String datePattern) {
        this.datePattern = datePattern;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public ParamSource getSource() {
        return source;
    }

    public void setSource(ParamSource source) {
        this.source = source;
    }

    public Module getModule() {
        return module;
    }

    public void setModule(Module module) {
        this.module = module;
    }

    public Config getConfig() {
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    @Override
    public String toJson(boolean isFormat, int lv) {
        if (lv <= 0) {
            throw new BtgSetRuntimerException("lv must be greater than 1");
        }

        int tabNum = lv - 1;

        StringBuilder sb = new StringBuilder();

        if (isFormat) {
            sb.append(StringUtil.getTab(tabNum)).append("{");
            sb.append("\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"id\":\"").append(id).append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"type\":\"").append(type.getName()).append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"datePattern\":\"").append(EmptyUtil.isNotEmpty(datePattern) ? datePattern : "").append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"name\":\"").append(EmptyUtil.isNotEmpty(name) ? name : "").append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"value\":\"").append(EmptyUtil.isNotEmpty(value) ? value : "").append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"desc\":\"").append(EmptyUtil.isNotEmpty(desc) ? desc : "").append("\"");
            sb.append(",\r\n");
            sb.append(StringUtil.getTab(tabNum + 1)).append("\"remark\":\"").append(EmptyUtil.isNotEmpty(remark) ? remark : "").append("\"");
            sb.append("\r\n");
            sb.append(StringUtil.getTab(tabNum)).append("}");
            return sb.toString();
        }

        sb.append("{");
        sb.append("\"id\":\"").append(id).append("\"");
        sb.append(",");
        sb.append("\"type\":\"").append(type.getName()).append("\"");
        sb.append(",");
        sb.append("\"datePattern\":\"").append(EmptyUtil.isNotEmpty(datePattern) ? datePattern : "").append("\"");
        sb.append(",");
        sb.append("\"name\":\"").append(EmptyUtil.isNotEmpty(name) ? name : "").append("\"");
        sb.append(",");
        sb.append("\"value\":\"").append(EmptyUtil.isNotEmpty(value) ? value : "").append("\"");
        sb.append(",");
        sb.append("\"desc\":\"").append(EmptyUtil.isNotEmpty(desc) ? desc : "").append("\"");
        sb.append(",");
        sb.append("\"remark\":\"").append(EmptyUtil.isNotEmpty(remark) ? remark : "").append("\"");
        sb.append("}");
        return sb.toString();
    }

    @Override
    public String toJson() {
        return toJson(true, 1);
    }

    @Override
    public String toXml(boolean isFormat, int lv) {
        if (lv <= 0) {
            throw new BtgSetRuntimerException("lv must be greater than 1");
        }

        int tabNum = lv - 1;

        StringBuilder sb = new StringBuilder();

        if (isFormat) {
            sb.append(StringUtil.getTab(tabNum)).append("<param");
            sb.append(" id=\"").append(id).append("\"");
            sb.append(" type=\"").append(type.getName()).append("\"");
            if (EmptyUtil.isNotEmpty(datePattern)) {
                sb.append(" datePattern=\"").append(datePattern).append("\"");
            }
            if (EmptyUtil.isNotEmpty(name)) {
                sb.append(" name=\"").append(name).append("\"");
            }
            if (EmptyUtil.isNotEmpty(desc)) {
                sb.append(" desc=\"").append(desc).append("\"");
            }
            if (EmptyUtil.isNotEmpty(remark)) {
                sb.append(" remark=\"").append(remark).append("\"");
            }
            sb.append(">");
            sb.append("<![CDATA[").append(value).append("]]>");
            sb.append("</param>");
            return sb.toString();
        }

        sb.append("<param");
        sb.append(" id=\"").append(id).append("\"");
        sb.append(" type=\"").append(type.getName()).append("\"");
        if (EmptyUtil.isNotEmpty(datePattern)) {
            sb.append(" datePattern=\"").append(datePattern).append("\"");
        }
        if (EmptyUtil.isNotEmpty(name)) {
            sb.append(" name=\"").append(name).append("\"");
        }
        if (EmptyUtil.isNotEmpty(desc)) {
            sb.append(" desc=\"").append(desc).append("\"");
        }
        if (EmptyUtil.isNotEmpty(remark)) {
            sb.append(" remark=\"").append(remark).append("\"");
        }
        sb.append(">");
        sb.append(value);
        sb.append("</param>");
        return sb.toString();
    }

    @Override
    public String toXml() {
        return toXml(true, 1);
    }

    @Override
    public String toString() {
        return this.toJson();
    }

    public boolean equals(Param target) {
        return this.toString().equals(target.toString());
    }

    /**
     * 获取param的配置path
     *
     * @return path
     */
    public String getPath() {
        if (this.getSource().equals(ParamSource.CONFIG)) {
            return this.getConfig().getId() + ">" + this.getId();
        } else if (this.getSource().equals(ParamSource.MODULE)) {
            return this.getConfig().getId() + ">" + this.getModule().getId() + ">" + this.getId();
        }
        return this.getId();
    }
}